package com.gitee.wsl.common.ui.draw.node


import androidx.annotation.FloatRange
import androidx.compose.ui.graphics.BlendMode
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.graphics.Path
import androidx.compose.ui.graphics.drawscope.DrawScope
import androidx.compose.ui.graphics.drawscope.DrawScope.Companion.DefaultBlendMode
import androidx.compose.ui.graphics.drawscope.DrawStyle
import androidx.compose.ui.graphics.drawscope.Fill
import androidx.compose.ui.graphics.drawscope.Stroke
import com.gitee.wsl.common.ui.base.ColorOrBrush
import com.gitee.wsl.common.ui.draw.api.HasFill
import com.gitee.wsl.common.ui.draw.api.HasStroke
import com.gitee.wsl.common.ui.draw.api.HasTransform
import com.gitee.wsl.common.ui.draw.api.Transform
import com.gitee.wsl.common.ui.draw.container.GroupNode
import com.gitee.wsl.common.ui.draw.style.toStroke

open class PathNode(val path: Path = Path()): Node(),
     HasStroke,
     HasFill,
     HasTransform,
     Path by path {

    override var transform: Transform? = null

    /**
     * Remove all segments of the path.
     * Todo should it be defined as a function of Path.
     */
     fun clearPath() {
        path.reset()
    }

    override fun DrawScope.draw() {
        fill?.let { fill ->
            /*when (fill) {
                is ColorOrBrush.Color -> drawPath(path, color = fill.value)
                is ColorOrBrush.Brush -> drawPath(path, fill.value)
            }*/
            drawPath(path, colorOrGradient = fill)
        }

        if (strokeWidth != null && strokeColor != null) {
            val stroke = strokeWidth?.toStroke(this) ?: Stroke()
            strokeColor?.let { colorOrGradient ->
                drawPath(
                    path,
                    colorOrGradient = colorOrGradient,
                    style = stroke
                )
                /*when (colorOrGradient) {
                    is ColorOrBrush.Color -> drawPath(
                        path,
                        color = colorOrGradient.value,
                        style = stroke
                    )
                    is ColorOrBrush.Brush -> drawPath(
                        path,
                        colorOrGradient.value,
                        style = stroke
                    )
                }*/
            }
        }
    }
}

fun GroupNode.path(block: PathNode.(GroupNode)->Unit){
    val node = PathNode()
    node.block(this)
    add(node)
}

fun GroupNode.path(path: Path,block: PathNode.(GroupNode)->Unit){
    val node = PathNode(path)
    node.block(this)
    add(node)
}

/*fun GroupNode.path(block: Path.(PathNode)->Unit){
    val path = Path()
    val node = PathNode(path)
    path.block(node)
    add(node)
}*/

fun DrawScope.drawPath(
    path: Path,
    colorOrGradient: ColorOrBrush,
    @FloatRange(from = 0.0, to = 1.0) alpha: Float = 1.0f,
    style: DrawStyle = Fill,
    colorFilter: ColorFilter? = null,
    blendMode: BlendMode = DefaultBlendMode
){
    when (colorOrGradient) {
        is ColorOrBrush.Color -> drawPath(
            path,
            color = colorOrGradient.value,
            style = style,
            colorFilter=colorFilter,
            blendMode = blendMode
        )
        is ColorOrBrush.Brush -> drawPath(
            path,
            colorOrGradient.value,
            style = style,
            colorFilter=colorFilter,
            blendMode = blendMode
        )
    }

}